const express = require('express');
const path = require('path');
const fs = require('fs').promises;
const { createLogger } = require('../utils/logger');
const { readJsonFile, writeJsonFile, CONFIG_DIR } = require('../utils/fileSystem');
const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc');
const timezone = require('dayjs/plugin/timezone');
dayjs.extend(utc);
dayjs.extend(timezone);
const CHINA_TZ = 'Asia/Shanghai';
function chinaNow() { return dayjs().tz(CHINA_TZ).format('YYYY-MM-DD HH:mm:ss'); }

const router = express.Router();
const logger = createLogger('config-api');

// Config file paths
const GLOBAL_CONFIG_FILE = path.join(CONFIG_DIR, 'global-config.json');

// Default global config structure
const DEFAULT_GLOBAL_CONFIG = {
  projectName: 'Monorepo Qiankun Template',
  projectVersion: '1.0.0',
  serverPort: 3100,
  logLevel: 'info',
  defaultStorageProvider: 'cos',
  supportedProviders: ['cos', 'oss', 'qiniu'],
  defaultCdnDomain: '',
  lastUpdated: chinaNow()
};

// Get global configuration
router.get('/global', async (req, res) => {
  try {
    const globalConfig = await readJsonFile(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG);
    
    res.json({
      code: 200,
      message: 'Global configuration retrieved successfully',
      data: globalConfig
    });
  } catch (error) {
    logger.error(`Error getting global config: ${error.message}`);
    res.status(500).json({
      code: 500,
      message: 'Failed to retrieve global configuration',
      error: error.message
    });
  }
});

// Update global configuration
router.put('/global', async (req, res) => {
  try {
    const {
      projectName,
      projectVersion,
      serverPort,
      logLevel,
      defaultStorageProvider,
      defaultCdnDomain
    } = req.body;
    
    const globalConfig = await readJsonFile(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG);
    
    // Update config with new values
    const updatedConfig = {
      ...globalConfig,
      projectName: projectName || globalConfig.projectName,
      projectVersion: projectVersion || globalConfig.projectVersion,
      serverPort: serverPort || globalConfig.serverPort,
      logLevel: logLevel || globalConfig.logLevel,
      defaultStorageProvider: defaultStorageProvider || globalConfig.defaultStorageProvider,
      defaultCdnDomain: defaultCdnDomain !== undefined ? defaultCdnDomain : globalConfig.defaultCdnDomain,
      lastUpdated: chinaNow()
    };
    
    // Save to file
    await writeJsonFile(GLOBAL_CONFIG_FILE, updatedConfig);
    
    res.json({
      code: 200,
      message: 'Global configuration updated successfully',
      data: updatedConfig
    });
  } catch (error) {
    logger.error(`Error updating global config: ${error.message}`);
    res.status(500).json({
      code: 500,
      message: 'Failed to update global configuration',
      error: error.message
    });
  }
});

// Get server status
router.get('/status', async (req, res) => {
  try {
    const rootDir = path.resolve(__dirname, '../../../');
    const packageJsonPath = path.join(rootDir, 'package.json');
    
    let packageJson = {};
    try {
      const packageJsonContent = await fs.readFile(packageJsonPath, 'utf8');
      packageJson = JSON.parse(packageJsonContent);
    } catch (error) {
      logger.warn(`Could not read package.json: ${error.message}`);
    }
    
    // Get config files
    const configFiles = [];
    try {
      const files = await fs.readdir(CONFIG_DIR);
      
      for (const file of files) {
        if (file.endsWith('.json')) {
          const filePath = path.join(CONFIG_DIR, file);
          const stats = await fs.stat(filePath);
          
          configFiles.push({
            name: file,
            size: stats.size,
            lastModified: stats.mtime
          });
        }
      }
    } catch (error) {
      logger.warn(`Error reading config directory: ${error.message}`);
    }
    
    res.json({
      code: 200,
      message: 'Server status retrieved successfully',
      data: {
        status: 'running',
        uptime: process.uptime(),
        timestamp: chinaNow(),
        version: packageJson.version || '1.0.0',
        node: process.version,
        platform: process.platform,
        configFiles
      }
    });
  } catch (error) {
    logger.error(`Error getting server status: ${error.message}`);
    res.status(500).json({
      code: 500,
      message: 'Failed to retrieve server status',
      error: error.message
    });
  }
});

// Reset configuration to defaults
router.post('/reset', async (req, res) => {
  try {
    const { type } = req.body;
    
    if (!type) {
      return res.status(400).json({
        code: 400,
        message: 'Type parameter is required'
      });
    }
    
    switch (type) {
      case 'global':
        await writeJsonFile(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG);
        break;
      case 'all':
        await writeJsonFile(GLOBAL_CONFIG_FILE, DEFAULT_GLOBAL_CONFIG);
        // Reset other configs as needed
        break;
      default:
        return res.status(400).json({
          code: 400,
          message: `Unknown config type: ${type}`
        });
    }
    
    res.json({
      code: 200,
      message: `Configuration ${type} reset to defaults successfully`
    });
  } catch (error) {
    logger.error(`Error resetting config: ${error.message}`);
    res.status(500).json({
      code: 500,
      message: 'Failed to reset configuration',
      error: error.message
    });
  }
});

// Create package.json for the deploy server
router.post('/init', async (req, res) => {
  try {
    const serverDir = path.resolve(__dirname, '../');
    const packageJsonPath = path.join(serverDir, 'package.json');
    
    const packageJson = {
      name: 'deploy-server',
      version: '1.0.0',
      description: 'Deploy server for monorepo qiankun template',
      main: 'server.js',
      scripts: {
        start: 'node server.js',
        dev: 'nodemon server.js'
      },
      dependencies: {
        express: '^4.18.2',
        cors: '^2.8.5',
        morgan: '^1.10.0',
        winston: '^3.8.2',
        uuid: '^9.0.0'
      },
      devDependencies: {
        nodemon: '^2.0.22'
      }
    };
    
    await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
    
    // Create README.md
    const readmePath = path.join(serverDir, 'README.md');
    const readmeContent = `# Deploy Server

This server manages the building and deployment of micro-frontend applications in the monorepo.

## Features

- Build management for micro-frontend apps
- Deployment to cloud storage providers
- Configuration management
- Build logs and status tracking

## API Endpoints

### Build API

- \`GET /api/build/config\` - Get build configuration
- \`PUT /api/build/config\` - Update build configuration
- \`GET /api/build/apps\` - Get available apps
- \`POST /api/build/:appName\` - Build an app
- \`GET /api/build/logs\` - Get build logs
- \`DELETE /api/build/logs\` - Clear build logs

### Deploy API

- \`GET /api/deploy/config\` - Get deploy configuration
- \`PUT /api/deploy/config\` - Update deploy configuration
- \`POST /api/deploy/:appName\` - Deploy an app
- \`POST /api/deploy\` - Deploy multiple apps

### Storage API

- \`GET /api/storage\` - Get all storage configurations
- \`GET /api/storage/:id\` - Get a specific storage configuration
- \`POST /api/storage\` - Create a new storage configuration
- \`PUT /api/storage/:id\` - Update a storage configuration
- \`DELETE /api/storage/:id\` - Delete a storage configuration
- \`POST /api/storage/test/:id\` - Test a storage configuration connection

### Config API

- \`GET /api/config/global\` - Get global configuration
- \`PUT /api/config/global\` - Update global configuration
- \`GET /api/config/status\` - Get server status
- \`POST /api/config/reset\` - Reset configuration to defaults
- \`POST /api/config/init\` - Initialize server configuration

## Getting Started

\`\`\`bash
# Install dependencies
npm install

# Start the server
npm start
\`\`\`
`;
    
    await fs.writeFile(readmePath, readmeContent, 'utf8');
    
    res.json({
      code: 200,
      message: 'Server initialized successfully',
      data: {
        packageJson,
        readme: 'Created README.md'
      }
    });
  } catch (error) {
    logger.error(`Error initializing server: ${error.message}`);
    res.status(500).json({
      code: 500,
      message: 'Failed to initialize server',
      error: error.message
    });
  }
});

module.exports = router; 